import { _decorator, Asset, AudioClip, Component, director, Enum, instantiate, Node, Prefab, ResolutionPolicy, resources, Sprite, SpriteFrame, sys, UITransform, v3, Vec3, view, Widget } from 'cc';
import { BaseManager } from './BaseManager';
import { WECHAT, WECHAT_MINI_PROGRAM } from 'cc/env';
const { ccclass, property } = _decorator;

/** 面板名称枚举 */
export enum PanelName {
    SettingPanel = 'SettingPanel',
    PropPanel = 'PropPanel',
    EnergyPanel = 'EnergyPanel',
    ShopPanel = 'ShopPanel',
    SuccessPanel = 'SuccessPanel',
    FailPanel = 'FailPanel',
    SidebarPanel = 'SidebarPanel',
    DailyPanel = 'DailyPanel',
    SignPanel = 'SignPanel',
    TipPanel = 'TipPanel',
    ShortcutPanel = 'ShortcutPanel'
}

/** 节点名称枚举 */
export enum NodeName {
    AudioNode = 'AudioNode'
}

/** 音频名称枚举 */
export enum AudioName {
    gamebgm = 'gamebgm',
    mainbgm = 'mainbgm',
    dianji = 'dianji',
    hecheng = 'hecheng',
    clickdish = 'clickdish',
    success = 'success',
    fail = 'fail',
    knockmalou = 'knockmalou',
    knockdish1 = 'knockdish1',
    knockdish2 = 'knockdish2'
}

@ccclass('ResourceManager')
export class ResourceManager extends BaseManager {

    managerName: string = '资源管理器'

    /** 总资源数量 */
    totalResNum: number = 0

    /** 加载资源数量 */
    loadedResNum: number = 0

    /** 预加载面板 */
    panels: Prefab[] = []

    /** 预加载节点 */
    nodes: Prefab[] = []

    /** 预加载音频片段 */
    audioClips: AudioClip[] = []

    init() {
        this.countResNum()
        this.preloadRes()
    }

    /** 计算资源数量 */
    countResNum() {
        let total: number = 0

        for (const key in PanelName) {
            total += 1
        }

        for (const key in NodeName) {
            total += 1
        }

        for (const key in AudioName) {
            total += 1
        }

        this.totalResNum = total
    }

    /** 预加载资源 */
    preloadRes() {
        this.loadedResNum = 0

        for (const key in PanelName) {
            let name: string = PanelName[key]
            this.loadRes('prefabs/panels/' + name, Prefab, (asset) => {
                this.panels[key] = asset as Prefab
                this.loadedResNum += 1
            })
        }

        for (const key in NodeName) {
            let name: string = NodeName[key]
            this.loadRes('prefabs/nodes/' + name, Prefab, (asset) => {
                this.nodes[key] = asset as Prefab
                this.loadedResNum += 1
            })
        }

        for (const key in AudioName) {
            let name: string = AudioName[key]
            this.loadRes('audios/' + name, AudioClip, (asset) => {
                this.audioClips[key] = asset as AudioClip
                this.loadedResNum += 1
            })
        }
    }

    /**
     * 对资源进行加载
     * @param path 路径
     * @param type 资源类型
     * @param success 加载成功后执行，参数为asset
     */
    loadRes(path: string, type: any, success: (asset: Asset) => void) {
        if (type == SpriteFrame) {
            path += '/spriteFrame'
        }
        resources.load(path, type, (err, asset) => {
            if (err)  {
                return console.log('加载错误：', err)
            }
            success(asset)
        })
    }

    /**
     * 获取面板预制件
     * @param panelName 面板枚举
     * @returns 面板预制件
     */
    getPanelPrefab(panelName: PanelName) {
        return this.panels[panelName]
    }

    /**
     * 打开预加载面板
     * @param panel 面板预制件
     * @param parent 父节点，默认为scene下名为"Canvas"的子节点
     * @returns 面板
     */
    openPanel(panel: Prefab, parent?: Node): Node {
        if (!panel) {
            return null
        }
        let pn: Node = instantiate(panel)
        pn.parent = parent ? parent : director.getScene().getChildByName("Canvas")
        return pn
    }

    /**
     * 加载预制件游戏
     * @param gameName 游戏名
     * @param z 3d项目中z轴
     */
    loadGame(gameName: string, z: number = 0) {
        this.loadRes('prefabs/games/' + gameName, Prefab, (asset) => {
            let g = instantiate(asset as Prefab)
            g.parent = director.getScene().getChildByName('Canvas')
            g.setPosition(0, 0, z)
        })
    }

    /**
     * 创建预制件节点
     * @param nodeName 节点枚举
     * @param parent 父节点，默认为scene下名为"Canvas"的子节点
     * @returns 节点
     */
    createNode(nodeName: NodeName, parent?: Node): Node {
        let node: Node = instantiate(this.nodes[nodeName])
        node.parent = parent ? parent : director.getScene().getChildByName("Canvas")
        return node
    }

    /**
     * 获取音频文件
     * @param audioName 音频名称
     * @returns 音频文件
     */
    getAudioClip(audioName: AudioName): AudioClip {
        return this.audioClips[audioName]
    }

    /**
     * 自适应竖屏模式
     * @param node 脚本所在节点
     */
    fitNode(node: Node) {
        let design = view.getDesignResolutionSize()
        if (!sys.isMobile) {
            view.setDesignResolutionSize(design.width, 1667, ResolutionPolicy.FIXED_HEIGHT)
        }
        else {
            view.setDesignResolutionSize(design.width, 1667, ResolutionPolicy.FIXED_WIDTH)
        }

        this.updateWidget(node)
    }

    updateWidget(node: Node) {
        let w: Widget = node.getComponent(Widget)
        if (!w) {
            w = node.addComponent(Widget)
        }
        var rect = view.getVisibleSize();// 获取实际显示的尺寸
        var dr = view.getDesignResolutionSize()// 获取设计分辨率
        // 设置手机端和pc端canvas的显示位置，在pc是横屏的，但是canvas应该是中间的手机位置。所以要左右减 
        //  实际屏幕宽度的一半减去手机屏宽的一半，就是pcBg距离Canvas左侧的距离
        if (!sys.isMobile && !WECHAT && !WECHAT_MINI_PROGRAM) { // pc端加背景图，实现中间显示手机界面
            w.right = rect.width / 2- (rect.height * dr.width / dr.height ) / 2
            w.left = rect.width / 2- (rect.height * dr.width / dr.height ) / 2
            w.top = 0
            w.bottom = 0
            w.updateAlignment()
        } else { // 手机端 屏幕宽度高，就是canvas的宽高。，距离是0就可以
            w.isAlignLeft = true
            w.isAlignRight = true
            w.isAlignTop = true
            w.isAlignBottom = true
            w.top = 0
            w.bottom = 0
            w.left = 0
            w.right = 0
            w.updateAlignment()
        }
    }

    spriteFitSquare(sprite: Sprite, height: number, width: number) {
        let node: Node = sprite.node
        let ut: UITransform = node.getComponent(UITransform)
        let scaleH: number = height / ut.height
        ut.height *= scaleH
        ut.width *= scaleH
        let scaleW: number = width / ut.width
        ut.height *= scaleW
        ut.width *= scaleW
    }
}


